package org.aplombh.java.awcing.basic.dp.memerizeDP;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * 给定一个 R 行 C 列的矩阵，表示一个矩形网格滑雪场。
 * <p>
 * 矩阵中第 i 行第 j 列的点表示滑雪场的第 i 行第 j 列区域的高度。
 * <p>
 * 一个人从滑雪场中的某个区域内出发，每次可以向上下左右任意一个方向滑动一个单位距离。
 * <p>
 * 当然，一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。
 * <p>
 * 下面给出一个矩阵作为例子：
 * <p>
 * 1  2  3  4 5
 * <p>
 * 16 17 18 19 6
 * <p>
 * 15 24 25 20 7
 * <p>
 * 14 23 22 21 8
 * <p>
 * 13 12 11 10 9
 * 在给定矩阵中，一条可行的滑行轨迹为 24−17−2−1。
 * <p>
 * 在给定矩阵中，最长的滑行轨迹为 25−24−23−…−3−2−1，沿途共经过 25 个区域。
 * <p>
 * 现在给定你一个二维矩阵表示滑雪场各区域的高度，请你找出在该滑雪场中能够完成的最长滑雪轨迹，并输出其长度(可经过最大区域数)。
 * <p>
 * 输入格式
 * 第一行包含两个整数 R 和 C。
 * <p>
 * 接下来 R 行，每行包含 C 个整数，表示完整的二维矩阵。
 * <p>
 * 输出格式
 * 输出一个整数，表示可完成的最长滑雪长度。
 * <p>
 * 数据范围
 * 1≤R,C≤300,
 * 0≤矩阵中整数≤10000
 * 输入样例：
 * 5 5
 * 1 2 3 4 5
 * 16 17 18 19 6
 * 15 24 25 20 7
 * 14 23 22 21 8
 * 13 12 11 10 9
 * 输出样例：
 * 25
 */
public class Skiing_901 {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String s = reader.readLine();
        int n = Integer.parseInt(s.split(" ")[0]);
        int m = Integer.parseInt(s.split(" ")[1]);

        Skiing skiing = new Skiing(n, m);
        for (int i = 1; i <= n; i++) {
            s = reader.readLine();
            for (int j = 1; j <= m; j++) {
                skiing.w[i][j] = Integer.parseInt(s.split(" ")[j - 1]);
            }
        }
        skiing.solve();
    }
}

class Skiing {
    public static final int N = 310;
    int[][] f = new int[N][N];
    int[][] w = new int[N][N];
    int n, m;

    int[] dx = {0, 0, -1, 1};
    int[] dy = {-1, 1, 0, 0};

    public Skiing(int n, int m) {
        this.n = n;
        this.m = m;
        for (int i = 0; i < N; i++) {
            Arrays.fill(f[i], -1);
        }
    }

    public void solve() {
        int res = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                // 找到最大长度
                res = Math.max(res, dp(i, j));
            }
        }
        System.out.println(res);
    }

    public int dp(int x, int y) {

        if (f[x][y] == -1) {
            f[x][y] = 1;
            // 在四个方向寻找最大值
            for (int i = 0; i < dx.length; i++) {
                // 横坐标
                int a = x + dx[i];
                // 纵坐标
                int b = y + dy[i];
                //  横坐标合法            纵坐标合法           上次高度比当前高度高
                if (a >= 1 && a <= n && b >= 1 && b <= m && w[x][y] > w[a][b]) {
                    f[x][y] = Math.max(f[x][y], dp(a, b) + 1);
                }
            }
        }
        return f[x][y];
    }
}
